package com.leyou.cart.service;

import com.leyou.cart.entity.Cart;
import com.leyou.common.auth.pojo.UserHolder;
import com.leyou.common.constants.LyConstants;
import com.leyou.common.exception.pojo.ExceptionEnum;
import com.leyou.common.exception.pojo.LyException;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.client.ItemClient;
import com.leyou.item.entity.Sku;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartService {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private ItemClient itemClient;

    /**
     * 分析购物车在redis中存储的数据结构，string， hash， list， set， zSet
     *  经过分析最终选择hash结构
     *  <key, <hashKey, Object>>
     *      key    ---userId
     *      hasKey ---skuId 快速找到对应sku，修改其中属性
     *      Object ---Sku购物车对象
     */
    public void addCart(Cart cart) {
        //获取当前用户在redis中的购物车的key
        String key = LyConstants.CART_PRE + UserHolder.getUserId();
        //通过key得到hash
        BoundHashOperations<String, String, String> cartHash = redisTemplate.boundHashOps(key);
        //得到hashKey
        String hashKey = cart.getSkuId().toString();
        //查看新添加的购物车对象是否存在于目前的购物车列表中
        Boolean hasKey = cartHash.hasKey(hashKey);
        //如果存在，就合并二者的数量
        if(hasKey){
            //得到目前购物车列表中对应的购物车对象
            String oldCartStr = cartHash.get(hashKey);
            //将字符串转成对象
            Cart oldCart = JsonUtils.toBean(oldCartStr, Cart.class);
            //将旧的购物车对象的数量合并到新的购物车对象中
            cart.setNum(cart.getNum()+oldCart.getNum());
        }
        //添加购物车
        cartHash.put(hashKey, JsonUtils.toString(cart));
    }

    public List<Cart> findCarts() {
        //获取当前用户在redis中的购物车的key
        String key = LyConstants.CART_PRE + UserHolder.getUserId();
        //查看当前用户是否有购物车
        if(!redisTemplate.hasKey(key)){
            throw new LyException(ExceptionEnum.CARTS_NOT_FOUND);
        }
        //获取当前用户的购物车的hash
        BoundHashOperations<String, String, String> hash = redisTemplate.boundHashOps(key);
        //判空
        if(hash==null || hash.size()==0){
            throw new LyException(ExceptionEnum.CARTS_NOT_FOUND);
        }
        //原生写法
//        List<String> cartStrs = hash.values();
//        List<Cart> cartList = new ArrayList<>();
//        for (String cartStr : cartStrs) {
//            Cart cart = JsonUtils.toBean(cartStr, Cart.class);
//            cartList.add(cart);
//        }
        //获取购物车列表
        List<Cart> carts = hash.values().stream()
                .map(cart -> JsonUtils.toBean(cart, Cart.class))//将所有字符串格式的购物车对象转成Cart对象格式
                .collect(Collectors.toList());
        return carts;
    }

    public void addCarts(List<Cart> carts) {
        carts.forEach(cart -> {
            addCart(cart);
        });
    }

    public void attention(Cart cart) {
        //获取当前用户在redis中的收藏的key
        String key = LyConstants.ATTENTION_KEY + UserHolder.getUserId();
        //通过key得到hash
        BoundHashOperations<String, String, String> cartHash = redisTemplate.boundHashOps(key);
        //得到hashKey
        String hashKey = cart.getSkuId().toString();
        //添加收藏
        cartHash.put(hashKey, JsonUtils.toString(cart));
    }

    public Integer collection(Cart cart) {
        //获取当前用户在redis中的收藏的key
        String key = LyConstants.ATTENTION_KEY + UserHolder.getUserId();
        //通过key得到hash
        BoundHashOperations<String, String, String> cartHash = redisTemplate.boundHashOps(key);
        //得到hashKey
        String hashKey = cart.getSkuId().toString();
        if (cartHash.hasKey(hashKey)){
            return 2;
        }
        return 1;
    }

    public List<Cart> getAttention() {
        //获取当前用户在redis中的收藏的key
        String key = LyConstants.ATTENTION_KEY + UserHolder.getUserId();
        //通过key得到hash
        BoundHashOperations<String, String, String> cartHash = redisTemplate.boundHashOps(key);
       if (cartHash==null||cartHash.size()==0){
           return null;
       }
        //获取收藏列表
        List<Cart> carts = cartHash.values().stream()
                .map(cart -> JsonUtils.toBean(cart, Cart.class))
                .collect(Collectors.toList());
        carts.forEach(cart -> {
            Sku sku = itemClient.findSkuById(cart.getSkuId());
            if (sku.getPrice()<cart.getPrice()){
                cart.setDepreciate(sku.getPrice()-cart.getPrice());
            }else {
                cart.setDepreciate(2L);
            }
        });
        return carts;

    }
    /**
     * 删除购物车商品
     * @param skuId
     * @return
     */
    public void delCarts(Long skuId) {
        //获取购物车key
        String cartKey = LyConstants.CART_PRE + UserHolder.getUserId();
        //获取购物车
        BoundHashOperations<String, String, String> cartMap = redisTemplate.boundHashOps(cartKey);
        try {
            cartMap.delete(skuId.toString());
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.DELETE_OPERATION_FAIL);
        }
    }
    /**
     * 修改购物车商品
     * @param skuId
     * @param num
     * @return
     */
    public void updataCart(Long skuId, Integer num) {
        //获取购物车key
        String cartKey = LyConstants.CART_PRE + UserHolder.getUserId();
        //获取购物车
        BoundHashOperations<String, String, String> cartMap = redisTemplate.boundHashOps(cartKey);
        try {
            String cartStr = cartMap.get(skuId.toString());
            Cart cart = JsonUtils.toBean(cartStr, Cart.class);
            cart.setNum(num);
            //更新购物车
            cartMap.put(skuId.toString(), JsonUtils.toString(cart));
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }

    public void rmAttention(Cart cart) {
        //获取当前用户在redis中的收藏的key
        String key = LyConstants.ATTENTION_KEY + UserHolder.getUserId();
        //通过key得到hash
        BoundHashOperations<String, String, String> cartHash = redisTemplate.boundHashOps(key);
        //得到hashKey
        String hashKey = cart.getSkuId().toString();
        //添加收藏
        if (cartHash.hasKey(hashKey)){
            cartHash.delete(hashKey);
        }
    }
}
